﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright company="DHGMS Solutions" file="Csv.cs">
//   2004-2012 DHGMS Solutions. Some Rights Reserved. Licensed under GNU General Public License version 2 (GPLv2)
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Dhgms.TplHelper.Controller.Task.SqlExport
{
    using System;
    using System.Data;
    using System.Data.Common;
    using System.Data.SqlClient;
    using System.Linq;

    using Dhgms.DataManager.Model.Info;

    using Kent.Boogaart.KBCsv;

    /// <summary>
    /// Exports a data reader to a csv file
    /// </summary>
    /// <typeparam name="TInformationClass">
    /// The information class that represents the output record format
    /// </typeparam>
    /// <typeparam name="TAdoNetHelperClass">
    /// The type for the ADO.NET helper class
    /// </typeparam>
    public abstract class Csv<TInformationClass, TAdoNetHelperClass> : Base
        where TInformationClass : Base<TInformationClass>, new()
        where TAdoNetHelperClass : Dhgms.DataManager.Model.Helper.AdoNet.Base<TInformationClass>, new()
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Csv{TInformationClass,TAdoNetHelperClass}"/> class. 
        /// </summary>
        /// <param name="taskName">
        /// Name of the task
        /// </param>
        /// <param name="connectionString">
        /// Database connection string
        /// </param>
        /// <param name="sqlCommand">
        /// The SQL command to execute
        /// </param>
        /// <param name="parameters">
        /// Parameters for the SQL command
        /// </param>
        /// <param name="outputFileName">
        /// The file we are saving to
        /// </param>
        protected Csv(
            string taskName, 
            string connectionString, 
            string sqlCommand, 
            SqlParameter[] parameters, 
            string outputFileName)
            : base(taskName, connectionString, sqlCommand, parameters)
        {
            if (outputFileName == null)
            {
                throw new ArgumentNullException("outputFileName");
            }

            this.OutputFileName = outputFileName;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the file we are saving to
        /// </summary>
        private string OutputFileName { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// Event for outputing the results
        /// </summary>
        /// <param name="dataReader">
        /// The results to output
        /// </param>
        /// <returns>
        /// The on output results.
        /// </returns>
        protected override long OnOutputResults(IDataReader dataReader)
        {
            var result = 0;

            using (var output = new CsvWriter(this.OutputFileName))
            {
                var infoClass = new TInformationClass();
                var adoNetHelper = new TAdoNetHelperClass();

                this.OnOverrideOutputFormat(output);
                var header = new HeaderRecord(infoClass.HeaderRecord.ToArray());

                while (dataReader.Read())
                {
                    // we do this to ensure the columns are in the same order as the header
                    var record = adoNetHelper.GetStronglyTypedObjectFromDataReaderRow(dataReader);

                    var values = record.ToStringArray();
                    var line = new DataRecord(header);
                    foreach (var value in values)
                    {
                        line.Add(value ?? string.Empty);
                    }

                    output.WriteRecord(line);

                    result++;
                }
            }

            return result;
        }

        /// <summary>
        /// Used to change the output format, if needed
        /// </summary>
        /// <param name="output">
        /// output object
        /// </param>
        protected virtual void OnOverrideOutputFormat(CsvWriter output)
        {
        }

        #endregion
    }
}